package skyhyun;

public class J18_OOP4 {

	// static
	// 일반적으로 객체를 생성하려면 생성자를 사용해야 함
	// 하지만, 생성자 없이 객체를 바로 사용할 수도 있음
	// static 예약어를 멤버변수나 메서드에 사용하면 객체생성없이 바로 클래스를 사용 할 수 있음
	
	// static 으로 선언된 멤버변수는 클래스명.멤버변수 형태로 사용
	// static 으로 선언된 메서드는 클래스명.메서드명 형태로 사용
	// static 으로 선언된 멤버변수는 클래스(공용) 변수라고 부르기도 함
	// 이것과 유사하게 C 언어에서는 전역변수라고 함
	
	// static 으로 선언된 멤버변수는 main() 메서드가 호출되기 전에 먼저 메모리에 변수공간이 생성됨
	// 반면에 객체는 main() 메서드가 호출되고 해당 클래스의 생성자가 호출되어야만 변수공간이 생성
	
	// OOP 작성기법 1
	// 프로그램 작성시 클래스는 용도(값, 처리)에 따라 최소 2개이상으로 나눠 작성하는 것을 추천
	// 값만을 저장하는 클래스 : value object 클래스
	// 값을 받아서 처리만 하는 클래스 : service 클래스
	
	// 인수전달방식
	
	public static void main(String[] args) {
		Rent r20131107001 = new Rent();
		r20131107001.rentno = 351;				// 대여번호
		r20131107001.bookno = 8746;			// 도서번호
		r20131107001.memberno = 68;		// 회원번호
		r20131107001.showRentInfo();		// 대여정보 출력

		// static 으로 선언된 클래스 사용
		StaticRent.rentno = 654;
		StaticRent.bookno = 12345678;
		StaticRent.memberno = 5467;
		
		StaticRent.showRentInfo();
		
		// 성적데이터 초기화
		SungJuk sj = new SungJuk();
		sj.kor = 32;
		sj.eng = 45;
		sj.mat = 55;
		// sj.tot = sj.kor + sj.eng + sj.mat;
		sj.tot = sj.showTotal();
		sj.avg = sj.showAvg();
		
		
		// 성적데이터 초기화 2
		SungJukVO sjvo = new SungJukVO(99, 98, 99);
		SungJukService s = new SungJukService();
		
		sjvo.tot = s.getTotal(sjvo.kor, sjvo.eng, sjvo.mat);
		// 생성자를 쓰지않고 메서드 호출
		sjvo.tot = SungJukService.getTotal2(sjvo.kor, sjvo.eng, sjvo.mat);
		
		System.out.println(sjvo.tot);
		
	} //main
	
} // class

	class Rent {
		int rentno = 0;
		int bookno = 0;
		int memberno = 0;
		
		// 대여정보 출력 showRentInfo
		void showRentInfo() {
			System.out.println("대여번호 : " + rentno);
			System.out.println("도서번호 : " + bookno);
			System.out.println("회원번호 : " + memberno);
			
		}
		
	}
	
	class StaticRent {									// 객체생성없이 클래스 사용 
		static int rentno = 0;
		static int bookno = 0;
		static int memberno = 0;
		String rentdate = null;					// static 선언이 되지 않았음
		
		// 대여정보 출력 showRentInfo
		static void showRentInfo() {
			System.out.println("대여번호 : " + rentno);
			System.out.println("도서번호 : " + bookno);
			System.out.println("회원번호 : " + memberno);
			// System.out.println("대출일자 : " + rentdate);	//	오류발생!
			// static 메서드에서는 비static 변수는 사용불가
			// 하지만, rentdate 를 사용하고 싶다면?
			StaticRent sr = new StaticRent();
			System.out.println("대출일자 : " + sr.rentdate);
			// 객체를 생성해서 사용해야 함
		}
		
	}
	
	class SungJuk {
		
		int kor;
		int eng;
		int mat;
		int tot;
		float avg;
		
		public SungJuk() { }
		public SungJuk(int kor, int eng, int mat) { 
			this.kor = kor;
			this.eng = eng;
			this.mat = mat;
		}

		int showTotal() {
			return kor + eng + mat;
		}
		
		float showAvg() {
			return (float)showTotal() / 3;
		}
		
	}
	
	// 성적 클래스 : 성적에 관련된 데이터만 저장
	// 즉, 멤버변수만 존재하고 그것을 처리하는 메서드는 없음
	// 메서드는 없음 - 값만 저장하는 클래스
	class SungJukVO {
		String name = null;
		int kor = 0;
		int eng = 0;
		int mat = 0;
		int tot = 0;
		
		public SungJukVO() { }
		public SungJukVO( int kor, int eng, int mat ) {
			this.kor = kor;
			this.eng = eng;
			this.mat = mat;
		}
		
	}
	
	// 성적 데이터에 대한 총점, 평균, 학점 등을 처리하는 클래스 
	class SungJukService {
		int getTotal(int kor, int eng, int mat) {
			return kor + eng + mat;
		}
		static int getTotal2(int kor, int eng, int mat) {
			return kor + eng + mat;
		}
		
	}
	
	
	
	
	
	
	
	
	